home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1993 October: Windmill on DISC / ADC Developer CD (1993-10) (''Windmill On DISC'')_iso / Dev.CD Oct 93.iso / System Software / U.S. System Software / System 7 Pro™ Beta 11 / Development Tools / Sample Code / Messaging Service Access Module / Internet PMSAM / Internet PMSAM source / spoolfromexternal.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-02-19  |  8.5 KB  |  357 lines  |  [TEXT/MPS ]

  1. /*-------------------------------------------------------------------
  2.  
  3. AOCE Post Office Protocol (POP) / Simple Mail Transfer Protocol (SMTP)
  4. Mail Service Access Module
  5.  
  6. written by Steve Falkenburg-- MacDTS
  7. ©1991-1993 Apple Computer, Inc.
  8.  
  9. --------------
  10. change history
  11. --------------
  12.  
  13. SJF        02/19/93    update for beta build    b1
  14. SJF        10/29/92    update to a11            a11
  15. SJF        06/08/92    update to a8            a8
  16. SJF        02/15/92    first working version    a4.5
  17. SJF        10/16/91    initial coding            a3
  18.  
  19. ---------------------------------------------------------------------*/
  20.  
  21. #ifndef __TYPES__
  22. #include <Types.h>
  23. #endif
  24.  
  25. #ifndef __OCE__
  26. #include <OCE.h>
  27. #endif
  28.  
  29. #ifndef __OCEMAIL__
  30. #include <OCEMail.h>
  31. #endif
  32.  
  33. #include <string.h>
  34.  
  35. #include "const.h"
  36. #include "gwerrors.h"
  37. #include "mytypes.h"
  38. #include "globals.h"
  39. #include "utils.h"
  40. #include "parser.h"
  41. #include "pop.constants.h"
  42. #include "pop.protocol.h"
  43. #include "convertaddress.h"
  44. #include "spoolsystem.h"
  45. #include "spooltoaoce.h"
  46. #include "spoolfromexternal.h"
  47.  
  48.  
  49. // DoSlotPut
  50. //
  51. // called to get messages for this slot from the external network and put them into
  52. // the system via the toolbox
  53. //
  54. OSErr DoSlotPut(SlotSpec *slot)
  55. {
  56.     OSErr err;
  57.     unsigned long popServerAddress,popConnID;
  58.     short numMessages,numMsgIDs,messageIDIndex;
  59.     long mboxLength;
  60.     TMsgIDList messageIDs;        // allocated by routine called from here, de-allocated by us
  61.     TMsgID curMessageID;
  62.     Ptr messageData;            // allocated by routine called from here, de-allocated by us
  63.     
  64.     TraceExecution("\pDoSlotPut");
  65.  
  66.     /* first, we need to grab the letters from POP and spool them */
  67.     
  68.     err = ConvertStringToAddr(slot->specInfo.popServer,&popServerAddress);
  69.     if (err!=noErr) {
  70.         return kInvalidPopServer;
  71.     }
  72.         
  73.     err = POP_InitiateConnection(popServerAddress,kPopPort,slot->dirIdentity.userName,slot->dirIdentity.password,&popConnID);
  74.     if (err!=noErr) {
  75.         return err;
  76.     }
  77.     
  78.     err = POP_GetDropStats(popConnID,&numMessages,&mboxLength);
  79.     if (err!=noErr) {
  80.         POP_CloseConnection(popConnID);
  81.         return err;
  82.     }
  83.     
  84.     err = POP_GetMessageIDs(popConnID,&messageIDs,&numMsgIDs);    // messageIDs allocated by call
  85.     if (err!=noErr) {
  86.         POP_CloseConnection(popConnID);
  87.         return err;
  88.     }
  89.  
  90.     for (messageIDIndex=0; messageIDIndex<numMsgIDs; messageIDIndex++) {
  91.         curMessageID = messageIDs[messageIDIndex];
  92.         err = POP_GetMessage(popConnID,curMessageID,&messageData);
  93.         if (err==noErr) {
  94.             err = SendPOPToAOCE(messageData,slot);
  95.             if (err!=noErr) {
  96.                 POP_CloseConnection(popConnID);
  97.                 return err;
  98.             }
  99.             DisposPtrChk(messageData);
  100.             if (MemError()!=noErr) {
  101.                 POP_CloseConnection(popConnID);
  102.                 return err;
  103.             }
  104.             err = POP_DeleteMessage(popConnID,curMessageID);
  105.         }
  106.         if (err!=noErr) {
  107.             POP_CloseConnection(popConnID);
  108.             return err;
  109.         }
  110.     }
  111.     
  112.     if (numMsgIDs!=0) {
  113.         DisposPtrChk(messageIDs);
  114.         if (MemError()!=noErr) {
  115.             POP_CloseConnection(popConnID);
  116.             return err;
  117.         }
  118.     }
  119.  
  120.     err = POP_CloseConnection(popConnID);
  121.     return err;
  122. }
  123.  
  124.  
  125. OSErr SendPOPToAOCE(Ptr messageData,SlotSpec *slot)
  126. {
  127.     FSSpec spoolSpec;
  128.     OSErr err;
  129.     
  130.     err = CreateSpoolFile(&spoolSpec);    // make our spool file
  131.     if (err!=noErr)
  132.         return err;
  133.  
  134.     err = SpoolFromPOP(&spoolSpec,messageData,slot);
  135.     if (err==noErr)
  136.         err = SpoolIntoAOCE(&spoolSpec,slot);
  137.     
  138.     RemoveSpoolFile(&spoolSpec);
  139.     return err;
  140. }
  141.  
  142.  
  143. OSErr SpoolFromPOP(FSSpec *spoolSpec,Ptr messageData,SlotSpec *slot)
  144. {
  145.     long headerLength,bodyLength;
  146.     OSErr err;
  147.     char *header,*body,*curr;
  148.     char headerData[512];
  149.     RString rStr;
  150.         
  151.     for (curr=messageData;(*curr && (*curr!=CR || *(curr+1)!=CR)); curr++);    // find header separator
  152.     curr++; // step over first CR to end header with CR
  153.     *curr = '\0'; // null terminate header
  154.     
  155.     header = messageData;        // get pointers to header, body
  156.     body = curr+1;
  157.     
  158.     headerLength = strlen(header);
  159.     bodyLength = strlen(body);
  160.  
  161.     // spool message body
  162.     
  163.     err = SpoolToFile(spoolSpec,kTextContent,kContentCreator,0,body,bodyLength);
  164.     if (err!=noErr)
  165.         return err;
  166.     
  167.     // spool from
  168.     
  169.     err = ExtractHeaderLine("From:",headerData,header);
  170.     if (err==noErr) {
  171.         err = SpoolAddresses(headerData,spoolSpec,kFromType,kAddrCreator,slot);
  172.         if (err!=noErr)
  173.             return err;
  174.     }
  175.     else {
  176.         // no from address, so put ourselves in the from...
  177.         strcpy(headerData,slot->dirIdentity.userName);
  178.         strcat(headerData,"@");
  179.         strcat(headerData,slot->specInfo.popServer);
  180.         err = SpoolAddresses(headerData,spoolSpec,kFromType,kAddrCreator,slot);
  181.         if (err!=noErr)
  182.             return err;
  183.     }
  184.     
  185.     // spool to
  186.     
  187.     err = ExtractHeaderLine("To:",headerData,header);
  188.     if (err==noErr) {
  189.         err = SpoolAddresses(headerData,spoolSpec,kToType,kAddrCreator,slot);
  190.         if (err!=noErr)
  191.             return err;
  192.     }
  193.     else {
  194.         // no to address, so put ourselves in as to so things will work (somewhat)
  195.         strcpy(headerData,slot->dirIdentity.userName);
  196.         strcat(headerData,"@");
  197.         strcat(headerData,slot->specInfo.popServer);
  198.         err = SpoolAddresses(headerData,spoolSpec,kToType,kAddrCreator,slot);
  199.         if (err!=noErr)
  200.             return err;
  201.     }
  202.             
  203.     // spool CC (optional)
  204.     
  205.     err = ExtractHeaderLine("Cc:",headerData,header);
  206.     if (err==noErr) {
  207.         err = SpoolAddresses(headerData,spoolSpec,kCCType,kAddrCreator,slot);
  208.         if (err!=noErr)
  209.             return err;
  210.     }
  211.     
  212.     // spool BCC (optional)
  213.     
  214.     err = ExtractHeaderLine("Bcc:",headerData,header);
  215.     if (err==noErr) {
  216.         err = SpoolAddresses(headerData,spoolSpec,kBCCType,kAddrCreator,slot);
  217.         if (err!=noErr)
  218.             return err;
  219.     }
  220.     
  221.     // spool subject
  222.     
  223.     err = ExtractHeaderLine("Subject:",headerData,header);
  224.     if (err==noErr) {
  225.         OCECToRString(headerData,smRoman,&rStr,kRStringMaxBytes);
  226.         err = SpoolToFile(spoolSpec,kSubjectType,kAttribCreator,0,(Ptr)&rStr,(unsigned long)rStr.dataLength+4);
  227.         if (err!=noErr)
  228.             return err;
  229.     }
  230.     
  231.     return noErr;
  232. }
  233.  
  234.  
  235. OSErr ExtractHeaderLine(char *header,char *contents,char *text)
  236. {
  237.     char *lineEnd,*curLine,*tmpWord;
  238.     
  239.     lineEnd = text;
  240.     while (*lineEnd) {
  241.         GetLine(&curLine,&lineEnd);
  242.         if (strstr(curLine,header)==curLine) {
  243.             GetWord(&tmpWord,&curLine);            
  244.             CopyLine(contents,curLine);
  245.             return noErr;
  246.         }
  247.     }
  248.  
  249.     return kUnexpectedDataCondition;
  250. }
  251.  
  252.  
  253. OSErr SpoolAddresses(char *headerLine,FSSpec *spoolSpec,OSType spoolType,OSType spoolCreator,SlotSpec *slot)
  254. {
  255.     OSErr err;
  256.     short index;
  257.     char *tAddress,*startAddr,*endAddr,*realName;
  258.     char singleAddr[256];
  259.     short addrLen;
  260.     
  261.     // rli variables
  262.     
  263.     RLI rli;
  264.     PackedRLI pRLI;
  265.  
  266.     // rid types
  267.     
  268.     CreationID cid;
  269.     RString rName,rType;
  270.     LocalRecordID localRID;
  271.     RecordID RID;
  272.  
  273.     DSSpec theRecipient;
  274.     char pRecipient[kMaxRecipSize];
  275.     unsigned long pRecipLength;
  276.     RString xtnValueRStr;
  277.     
  278.     err = noErr;
  279.     index = 0;
  280.     
  281.     while (*headerLine && err==noErr) {
  282.         GetField(&tAddress,&headerLine,',',&addrLen);
  283.         strncpy(singleAddr,tAddress,addrLen);
  284.         singleAddr[addrLen] = '\0';
  285.         realName = startAddr = endAddr = nil;
  286.         
  287.         // search for "xxxxx <addr>" style address
  288.         
  289.         if (startAddr=strstr(singleAddr,"<")) {        // got one
  290.             *startAddr = '\0';
  291.             startAddr++;
  292.             endAddr = strstr(startAddr,">");
  293.             *endAddr = '\0';
  294.             realName = singleAddr;
  295.         }
  296.         
  297.         // if not, assume "addr (xxxxxxx)" style address
  298.         
  299.         else {
  300.             startAddr = singleAddr;
  301.             endAddr=strstr(singleAddr," ");
  302.             if (endAddr) {
  303.                 *endAddr = '\0';
  304.                 realName = strstr(singleAddr,"(");
  305.                 if (realName) {
  306.                     endAddr = strstr(realName,")");
  307.                     if (endAddr)
  308.                         *endAddr = '\0';
  309.                     else
  310.                         realName = nil;
  311.                 }
  312.             }
  313.         }
  314.         
  315.         if (!startAddr)                                // at this point, realName points to the user's real name
  316.             return kUnexpectedDataCondition;        // and startAddr points to their e-mail address
  317.  
  318.         if (!realName || *realName==0)
  319.             realName = startAddr;
  320.             
  321.         // make our RLI (and pack it)
  322.         
  323.         OCENewRLI(&rli,(DirectoryNamePtr)&slot->directoryName,&slot->discriminator,kNULLDNodeNumber,nil);
  324.         if (!OCEValidRLI(&rli))
  325.             return kUnexpectedAOCECondition;
  326.         err = OCEPackRLI(&rli,&pRLI,kRLIMaxBytes);
  327.         if (err!=noErr)
  328.             return err;
  329.         if (!OCEValidPackedRLI(&pRLI))
  330.             return kUnexpectedAOCECondition;
  331.             
  332.         // set up name, type rstrings and creation ID for local RID
  333.         
  334.         OCESetCreationIDtoNull(&cid);
  335.         OCECToRString(kUserRecTypeBody,smRoman,&rType,kRStringMaxBytes);
  336.         OCECToRString(realName,smRoman,&rName,kRStringMaxBytes);
  337.         
  338.         // make the local RID and the RID
  339.  
  340.         OCENewLocalRecordID (&rName,&rType,&cid,&localRID);                            
  341.         OCENewRecordID(&pRLI,&localRID,&RID);
  342.  
  343.         theRecipient.entitySpecifier = &RID;
  344.         theRecipient.extensionType = kPopAddrType;
  345.         OCECToRString(startAddr,smRoman,&xtnValueRStr,kRStringMaxChars);
  346.         theRecipient.extensionSize = xtnValueRStr.dataLength+4;
  347.         theRecipient.extensionValue = (Ptr)&xtnValueRStr;
  348.                 
  349.         pRecipLength = OCEPackedDSSpecSize(&theRecipient);
  350.         OCEPackDSSpec(&theRecipient,(PackedDSSpec *)&pRecipient,pRecipLength);
  351.         
  352.         err = SpoolToFile(spoolSpec,spoolType,spoolCreator,index++,(Ptr)&pRecipient,pRecipLength);
  353.     }
  354.     
  355.     return err;
  356. }
  357.